﻿using System;
using System.Collections.Generic;
using SymbolIntegration.core.Helpers;

namespace SymbolIntegration.core.Expressions.Functions
{
    public class CosFunction : FuncExpression
    {
        internal static CosFunction ParseItself(string expression, int position, int size)
        {
            var result = new CosFunction();
            result.InnerParseItself(expression, position, size);
            return result;
        }

        public CosFunction(Expression argument):base(argument)
        {
            
        }

        protected CosFunction()
        {
            
        }

        public override Expression Clone()
        {
            var clone = new CosFunction(m_Argument);
            InnerCopy(clone);
            return clone;
        }

        protected internal override Expression IntegrateAsDependentFromVar(string variable, IIntegrator integrator)
        {
            Expression result;
            do
            {
                var polinom = m_Argument.FormatToPolinom(variable);
                if (polinom != null && polinom.GetMaxPower() == 1)
                {
                    result = new SinFunction(m_Argument) / polinom.GetConstantAt(1);
                    break;
                }

                result = integrator.TryIntegrateMultipliers(new List<Expression>{SetNegate(false)}, variable);
            } 
            while (false);

            result = result.InvertNegate(IsNegate);
            return result;
        }

        public override FunctionType FunctionType
        {
            get { return FunctionType.Cos; }
        }

        protected override string GetFunctionName()
        {
            return "cos";
        }

        protected override ConstantExpression Apply(double constant)
        {
            return new ConstantExpression(Math.Cos(constant));
        }

        protected override Expression InnerFuncDifferentiate(string argument)
        {
            var result = new SinFunction(m_Argument).SetNegate(!IsNegate);
            return result; 
        }
    }
}